
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.channels.FileChannel;
import java.nio.channels.SocketChannel;


/**
 * @author mikkin
 *
 */
public class FileServer extends Thread{
	private String hostName;
	private int port;
	private String fileName;
	private ObjectOutputStream objOut;
	private ObjectInputStream objIn;
	private FileChannel incoming;
	private SocketChannel clientSocket;
	
	/**
	 * 
	 * @param hostName
	 * @param port
	 * @param fileName
	 */
	public FileServer(String hostName, int port, String fileName){
		this.hostName = hostName;
		this.port = port;
		this.fileName = fileName;
		
		File f = new File(this.fileName);
		if(!f.exists()){
			System.err.println("Error: The given file does not exist");
			System.exit(0);
		}
		
	}

	/* (non-Javadoc)
	 * @see java.lang.Thread#run()
	 */
	public void run(){
		//SocketChannel clientSocket = null;
		try{
			clientSocket = SocketChannel.open(new InetSocketAddress(this.hostName, this.port));
			InputStream inStream = clientSocket.socket().getInputStream();
			OutputStream outStream = clientSocket.socket().getOutputStream();
			
			objOut = new ObjectOutputStream(outStream);
			objIn = new ObjectInputStream(inStream);
			
			objOut.writeUnshared("FileServer");
			objOut.writeUnshared(this.fileName);
			System.out.println("Sending file... ");
			
			FileInputStream fin = new FileInputStream(this.fileName);
			FileChannel fChan = fin.getChannel();
			int maxCount = (64 * 1024 * 1024) - (32 * 1024);
	        long size = fChan.size();
	        long position = 0;
	        
	        objOut.writeUnshared(size);
	        
	        System.out.println(size);
	        long time = System.currentTimeMillis();
	        while (position < size) {
	        	position += fChan.transferTo(position, maxCount, clientSocket);
	        	System.out.println(position);
	        	System.out.println("Remaining: " + (size-position));
	        }
	        time = System.currentTimeMillis() - time;
	        System.out.println("Time taken: " + time);
 		}catch(Exception e){
			e.printStackTrace();
		}finally{
			try {
				clientSocket.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * @param args
	 */
	public static void main(String args[]){
		if(args.length != 3){
			System.err.println("Usage error");
			System.exit(0);
		}
		new FileServer(args[0], Integer.parseInt(args[1]), args[2]).start();
	}
}
